package com.longcai.cm.api.api4login;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.longcai.cm.api.request.CollectParam;
import com.longcai.cm.api.response.MemberInfo;
import com.longcai.cm.auth.Login;
import com.longcai.cm.auth.LoginUser;
import com.longcai.cm.auth.token.LoginUserInfo;
import com.longcai.cm.auth.token.RequestUtil;
import com.longcai.cm.bean.Page;
import com.longcai.cm.bean.R;
import com.longcai.cm.common.constant.DomainConfig;
import com.longcai.cm.common.utils.StringUtil;
import com.longcai.cm.common.utils.StringUtils;
import com.longcai.cm.domain.*;
import com.longcai.cm.domain.vm.MemberVipViewModel;
import com.longcai.cm.moudules.system.bean.DicCode;
import com.longcai.cm.moudules.system.service.SysDicCodeService;
import com.longcai.cm.service.*;
import com.longcai.cm.utils.GeoCalculator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.List;

/**
 * @author libingxing
 */
@RestController
@Api(tags = "用户信息相关")
@RequestMapping("/api/member")
public class ApiMemberController {

    @Resource
    private FaMemberService memberService;

    @Resource
    private JaMemberAssetService memberAssetService;

    @Resource
    private VOrderListService orderListService;

    @Resource
    private VMemberCouponListService memberCouponListService;

    @Resource
    private JaMemberCollectionService memberCollectionService;

    @Resource
    private VCollectionListService collectionListService;

    @Resource
    private JaMemberLogIntegralService memberLogIntegralService;

    @Resource
    private RedisService redisService;

    @Resource
    private JaMemberVipService memberVipService;

    @Resource
    private JaVipInfoService vipInfoService;

    @Resource
    private VGoodInfoListService goodInfoListService;

    @Resource
    private JaCouponService couponService;

    @Resource
    private SysDicCodeService sysDicCodeService;

    @Login
    @PostMapping("/memberInfo")
    @ApiOperation("用户信息")
    public R<MemberInfo> memberInfo(
            @ApiIgnore @LoginUser FaMember member
    ) {
        final MemberInfo result = new MemberInfo();
        final FaMember loginUser = memberService.getById(member.getId());
        BeanUtils.copyProperties(loginUser, result);
        result.setMobile(StringUtil.convertStr(result.getMobile(), 4, 3, 7));
//        积分
        final JaMemberAsset memberAsset = memberAssetService.getMemberAsset(member.getId() + "");
        result.setIntegral(memberAsset.getIntegral().setScale(0, RoundingMode.HALF_UP));
//        上级
        if (member.getPid() != null && member.getPid() > 0) {
            final FaMember parent = memberService.getById(member.getPid());
            result.setParentName(parent.getWxname());
        } else {
            result.setParentName("");
        }
        result.setMemberVipViewModel(memberVipService.getVipInfo(member.getId()));
//        各类状态订单数量
        final List<VOrderList> orderList = orderListService.lambdaQuery()
                .select(VOrderList::getOrderStatus, VOrderList::getRefundStatus)
                .eq(VOrderList::getMemberId, member.getId())
                .ne(VOrderList::getOrderType, 4)
                .ne(VOrderList::getOrderType, 3)
                .list();
//        0待支付 1待使用 2待评价 3已完成 4已取消 5退款
        if (orderList.size() > 0) {
            result.setOrderCountUnPay(orderList.stream().filter(o -> o.getOrderStatus().equals(0)).count());
            result.setOrderCountUnUse(orderList.stream().filter(o -> o.getOrderStatus().equals(1)).count());
            result.setOrderCountUnComment(orderList.stream().filter(o -> o.getOrderStatus().equals(2)).count());
            result.setOrderCountRefund(orderList.stream().filter(o -> o.getOrderStatus().equals(5) && (o.getRefundStatus() != null && (o.getRefundStatus() == 0 || o.getRefundStatus() == 2))).count());
        }
        final String servicePhone = sysDicCodeService.getTextValueByCode(DicCode.SERVICE_PEOPLE);
        result.setServicePhone(servicePhone);
        return R.success(result);
    }

    @PostMapping("/vipInfo")
    @ApiOperation("vip详情")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "会员id", name = "id", dataType = "String", required = true)
    })
    public R<JaVipInfo> vipInfo(
            String id, HttpServletRequest request
    ) {
        final JaVipInfo vip = vipInfoService.getById(id);
        vip.setVipProduct(goodInfoListService.lambdaQuery().isNotNull(VGoodInfoList::getVipPrice).last(" limit 1").one());
        vip.setCouponList(couponService.lambdaQuery().eq(JaCoupon::getSource, 2).orderByAsc(JaCoupon::getDiscountAmount).list());
        try {
            final LoginUserInfo userInfo = RequestUtil.getUserInfoByRequest(request);
            vip.setMemberVipViewModel(memberVipService.getVipInfo(Integer.valueOf(userInfo.getUserId())));
        } catch (Exception e) {
            vip.setMemberVipViewModel(new MemberVipViewModel(0));
        }
        return R.success(vip);
    }

    @Login
    @PostMapping("/editUser")
    @ApiOperation("编辑用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "姓名", name = "wxname", dataType = "int", required = true),
            @ApiImplicitParam(value = "头像", name = "avatar", dataType = "int", required = true),
            @ApiImplicitParam(value = "状态(0-未使用 1-已使用 2-已失效)", name = "status", dataType = "int", required = true),
    })
    public R<Object> editUser(
            @ApiIgnore @LoginUser FaMember member,
            String wxname, String avatar
    ) {
        if (StringUtils.isNotBlank(wxname)) {
            member.setWxname(wxname);
        }
        if (StringUtils.isNotBlank(avatar)) {
            member.setAvatar(DomainConfig.LOCALHOST + avatar);
        }
        memberService.updateById(member);
        redisService.updateUser(JSON.toJSONString(member), member.getId() + "");
        return R.success();
    }

    @Login
    @PostMapping("/myOrderList")
    @ApiOperation("我的订单")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页", name = "page", dataType = "int", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "int", required = true),
            @ApiImplicitParam(value = "搜索 产品名称 订单号", name = "keyword", dataType = "int", required = true),
            @ApiImplicitParam(value = "订单状态 0待支付 1待使用 2待评价 3已完成 4已取消 5退款", name = "orderStatus", dataType = "int", required = true),
    })
    public R<Page<List<VOrderList>>> myOrderList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer rows,
            @ApiIgnore @LoginUser FaMember member,
            String orderStatus, String keyword
    ) {
        final LambdaQueryWrapper<VOrderList> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VOrderList::getMemberId, member.getId());
        if (StringUtils.isNotBlank(orderStatus)) {
            wrapper.eq(VOrderList::getOrderStatus, orderStatus);
        }
        wrapper.ne(VOrderList::getOrderType, 3).ne(VOrderList::getOrderType, 4);
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.and(
                    eq -> eq.like(VOrderList::getOrderNum, keyword)
                            .or().like(VOrderList::getGoodName, keyword)
            );
        }
        final long total = orderListService.count(wrapper);
        final Page<List<VOrderList>> result = new Page<>(page, rows, total);
        wrapper.last(result.convertPage());
        wrapper.orderByDesc(VOrderList::getCreateTime);
        final List<VOrderList> list = orderListService.list(wrapper);
        result.setContent(list);
        return R.success(result);
    }

    @Login
    @PostMapping("/memberCouponList")
    @ApiOperation("我的优惠券")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页", name = "page", dataType = "int", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "int", required = true),
            @ApiImplicitParam(value = "状态(0-未使用 1-已使用 2-已失效)", name = "status", dataType = "int", required = true),
            @ApiImplicitParam(value = "来源(1团券 2会员券)", name = "source", dataType = "int", required = true),
    })
    public R<Page<List<VMemberCouponList>>> memberCouponList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer rows,
            @ApiIgnore @LoginUser FaMember member,
            String status, String source
    ) {
        LambdaQueryWrapper<VMemberCouponList> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VMemberCouponList::getMemberId, member.getId());
        if (StringUtils.isNotBlank(status)) {
            wrapper.eq(VMemberCouponList::getStatus, status);
        }
        if (StringUtils.isNotBlank(source)) {
            final MemberVipViewModel vipInfo = memberVipService.getVipInfo(member.getId());
//            不是会员不能用会员券
            if (vipInfo.getIfVip() == 1) {
                wrapper.eq(VMemberCouponList::getSource, source);
            } else {
                if ("1".equals(source)) {
                    wrapper.eq(VMemberCouponList::getSource, source);
                }else {
//                    不是会员 会员券列表给他搞没了
                    wrapper.eq(VMemberCouponList::getSource, "10");
                }
            }
        }
        final long total = memberCouponListService.count(wrapper);
        final Page<List<VMemberCouponList>> result = new Page<>(page, rows, total);
        wrapper.last(result.convertPage());
        wrapper.orderByDesc(VMemberCouponList::getCreateTime);
        final List<VMemberCouponList> list = memberCouponListService.list(wrapper);
        result.setContent(list);
        return R.success(result);
    }

    @Login
    @PostMapping("/collect")
    @ApiOperation("收藏/取消收藏")
    public R<Object> collect(
            @ApiIgnore @LoginUser FaMember member,
            CollectParam param
    ) {
        JaMemberCollection one = memberCollectionService.lambdaQuery().eq(JaMemberCollection::getMemberId, member.getId())
                .eq(JaMemberCollection::getType, param.getType())
                .eq(JaMemberCollection::getTransId, param.getTransId())
                .one();
        if (one == null) {
            one = new JaMemberCollection();
            BeanUtils.copyProperties(param, one);
            one.setId(StringUtil.getUuid());
            one.setCreateTime(DateUtil.now());
            one.setMemberId(member.getId());
            memberCollectionService.save(one);
            return R.success("已收藏");
        } else {
            memberCollectionService.removeById(one.getId());
            return R.success("收藏已取消");
        }
    }

    @Login
    @PostMapping("/myCollection")
    @ApiOperation("我的收藏-详情见门店相关接口")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页", name = "page", dataType = "int", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "int", required = true),
            @ApiImplicitParam(value = "收藏类型 1驾校 2车商 3门店", name = "type", dataType = "int", required = true),
            @ApiImplicitParam(value = "经度", name = "lng", dataType = "String", required = true),
            @ApiImplicitParam(value = "纬度", name = "lat", dataType = "String", required = true),
    })
    public R<Page<List<VCollectionList>>> myCollection(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer rows,
            @ApiIgnore @LoginUser FaMember member,
            @RequestParam(defaultValue = "1") Integer type,
            @RequestParam(defaultValue = "37") Double lat,
            @RequestParam(defaultValue = "112") Double lng
    ) {
        final LambdaQueryWrapper<VCollectionList> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VCollectionList::getMemberId, member.getId());
        wrapper.eq(VCollectionList::getType, type);
        final long total = collectionListService.count(wrapper);
        final Page<List<VCollectionList>> result = new Page<>(page, rows, total);
        wrapper.last(result.convertPage());
        wrapper.orderByDesc(VCollectionList::getCreateTime);
        final List<VCollectionList> list = collectionListService.list(wrapper);
        if (type != 2) {
            for (VCollectionList collectionList : list) {
                collectionList.setDistance(GeoCalculator.calculateDistance(lat, lng, new BigDecimal(collectionList.getLat()).doubleValue(), new BigDecimal(collectionList.getLng()).doubleValue()));
            }
            list.sort(Comparator.comparingInt(VCollectionList::getDistance));
        }
        result.setContent(list);
        return R.success(result);
    }

    @Login
    @PostMapping("/memberAmountLogList")
    @ApiOperation("余额变动明细")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "当前页", name = "page", dataType = "int", required = true),
            @ApiImplicitParam(value = "条数", name = "rows", dataType = "int", required = true),
            @ApiImplicitParam(value = "变动类型( 0: 减少 1:增加  )", name = "type", dataType = "int", required = true),
    })
    public R<Page<List<JaMemberLogIntegral>>> memberAmountLogList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer rows,
            @ApiIgnore @LoginUser FaMember member,
            String type
    ) {
        final LambdaQueryWrapper<JaMemberLogIntegral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(JaMemberLogIntegral::getMemberId, member.getId());
        if (StringUtils.isNotBlank(type)) {
            wrapper.eq(JaMemberLogIntegral::getLogType, type);
        }
        final long total = memberLogIntegralService.count(wrapper);
        final Page<List<JaMemberLogIntegral>> result = new Page<>(page, rows, total);
        wrapper.last(result.convertPage());
        wrapper.orderByDesc(JaMemberLogIntegral::getCreateTime);
        final List<JaMemberLogIntegral> list = memberLogIntegralService.list(wrapper);
        result.setContent(list);
        return R.success(result);
    }

}
